本文同步更新於blog
情境:以下是某自助餐餐廳的情況
<?php
namespace App\FacadePattern\Buffet;
class IceCreamMachine
{
public function addIngredients()
{
//倒入牛奶、糖、鮮奶油、蛋黃等
return $this;
}
public function stir()
{
//攪拌均勻
return $this;
}
public function chill()
{
//使其冷藏
return $this;
}
public function squeeze()
{
//擠出霜淇淋
return '霜淇淋';
}
}
<?php
namespace App\FacadePattern\Buffet;
class CoffeeMachine
{
public function addCoffeeBeans()
{
//放入咖啡豆
return $this;
}
public function grind()
{
//研磨咖啡豆
return $this;
}
public function brew()
{
//沖煮咖啡
return $this;
}
public function stirWithMilk()
{
//與牛奶攪拌
return '拿鐵';
}
}
老闆認為目前的方式,客人必須知道霜淇淋機與咖啡機所有的操作流程。
不是那麼地友好,希望我們能寫個簡單的介面,讓客人更容易取得餐點。
需求一:替霜淇淋機與咖啡機設計簡單的介面,方便取用
<?php
namespace App\FacadePattern\Buffet\Facade;
use App\FacadePattern\Buffet\IceCreamMachine;
class IceCreamMachineFacade
{
public static function makeIceCream()
{
$iceCreamMachine = new IceCreamMachine();
return $iceCreamMachine
->addIngredients()
->stir()
->chill()
->squeeze();
}
}
<?php
namespace App\FacadePattern\Buffet\Facade;
use App\FacadePattern\Buffet\CoffeeMachine;
class CoffeeMachineFacade
{
public static function makeLatte()
{
$coffeeMachine = new CoffeeMachine();
return $coffeeMachine
->addCoffeeBeans()
->grind()
->brew()
->stirWithMilk();
}
}
<?php
namespace App\FacadePattern\Buffet;
use App\FacadePattern\Buffet\Facade\CoffeeMachineFacade;
use App\FacadePattern\Buffet\Facade\IceCreamMachineFacade;
class Program
{
public function makeIceCream()
{
return IceCreamMachineFacade::makeIceCream();
}
public function makeLatte()
{
return CoffeeMachineFacade::makeLatte();
}
}
這下子,客人終於不用知道太多,便能取得自己想要的餐點了。
[單一職責原則]
我們將子類別與接口類別視作兩種不同的職責。
[開放封閉原則]
對於客戶端與接口類別來說,並不會因為我們用了新的咖啡機而有所區別。
然而當子類別改動時可能會連帶修改到接口類別。
最後附上類別圖:
(註:若不熟悉 UML 類別圖,可參考UML類別圖說明。)
ʕ •ᴥ•ʔ:在這個例子中,我會覺得是霜淇淋機/咖啡機不對,
竟然沒有提供簡單的介面!